using System.Collections.Generic;
using System.Text;
using FluentDBC;

namespace ConsoleApplication
{
    public class ShoppingApplication
    {
        public ICustomerRepository CustomerRepository { get; private set; }

        public ICustomerService CustomerService { get; private set; }

        public ITaxStrategy TaxStrategy { get; private set; }

        public IFluentDBCConfiguration DBC { get; private set; }

        public ShoppingApplication()
            : this((ICustomerRepository)Container.GetInstance<ICustomerRepository>(),
                    (ICustomerService)Container.GetInstance<ICustomerService>(),
                    (ITaxStrategy)Container.GetInstance<ITaxStrategy>(),
                    (IFluentDBCConfiguration)Container.GetInstance<IFluentDBCConfiguration>())
        {
        }

        public ShoppingApplication(
            ICustomerRepository customerRepository,
            ICustomerService customerService,
            ITaxStrategy taxStrategy,
            IFluentDBCConfiguration dbc)
        {
            CustomerRepository = customerRepository;
            CustomerService = customerService;
            TaxStrategy = taxStrategy;
            DBC = dbc;
        }

        public string ProcessingInvoiceForAllCustomers()
        {
            DBC.ValidateContractForClass(this);

            var customers = CustomerRepository.GetAll();
            foreach (var customer in customers)
            {
                CustomerService.CalculateTax(customer, TaxStrategy);
            }

            return BuildReport(customers);
        }

        private static string BuildReport(IEnumerable<Customer> customers)
        {
            var builder = new StringBuilder();

            foreach (var customer in customers)
            {
                builder.AppendFormat("Id: {0}, Name: {1}, Gender: {2}, Address: {3}, Tax: {4}", customer.Id,
                                     customer.Name, customer.Gender, customer.Address, customer.Tax);
                builder.AppendLine();
            }

            return builder.ToString();
        }
    }
}